import Database from 'better-sqlite3';
import path from 'path';
import bcrypt from 'bcryptjs';
import { randomBytes } from 'crypto';

const DB_PATH = path.join(process.cwd(), 'data', 'delivery-management.db');

// 开发环境使用更低的bcrypt工作因子以提升性能
const BCRYPT_ROUNDS = process.env.NODE_ENV === 'production' ? 12 : 8;

export interface Role {
  id: number;
  code: string;
  name: string;
  description: string;
  permissions: string;
  created_at: string;
  updated_at: string;
}

export interface User {
  id: number;
  username: string;
  email: string;
  full_name: string;
  role_id: number;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface UserWithRole extends User {
  role_code: string;
  role_name: string;
  role_permissions: string;
}

export interface UserSession {
  id: number;
  user_id: number;
  session_token: string;
  expires_at: string;
  created_at: string;
}

export interface RolePermissions {
  canEditAll: boolean;
  canManageUsers: boolean;
  canManageRoles: boolean;
  dataSourceAccess: string[];
  editableFields?: {
    [tableType: string]: string[];
  };
}

export class UserManagement {
  private db: Database.Database;

  constructor() {
    this.db = new Database(DB_PATH, {
      readonly: false,
      fileMustExist: true
    });
    // 确保WAL模式
    this.db.pragma('journal_mode = WAL');
  }

  // 用户认证
  async authenticateUser(username: string, password: string): Promise<UserWithRole | null> {
    const stmt = this.db.prepare(`
      SELECT u.*, r.code as role_code, r.name as role_name, r.permissions as role_permissions
      FROM users u
      JOIN roles r ON u.role_id = r.id
      WHERE u.username = ? AND u.is_active = 1
    `);

    const user = stmt.get(username) as any;
    if (!user) return null;

    const isValidPassword = await bcrypt.compare(password, user.password);
    if (!isValidPassword) return null;

    // 移除密码字段
    delete user.password;
    return user as UserWithRole;
  }

  // 创建用户会话
  createSession(userId: number): string {
    const sessionToken = randomBytes(32).toString('hex');
    const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); // 24小时后过期

    const stmt = this.db.prepare(`
      INSERT INTO user_sessions (user_id, session_token, expires_at)
      VALUES (?, ?, ?)
    `);
    
    stmt.run(userId, sessionToken, expiresAt);
    return sessionToken;
  }

  // 验证会话
  validateSession(sessionToken: string): UserWithRole | null {
    const stmt = this.db.prepare(`
      SELECT u.*, r.code as role_code, r.name as role_name, r.permissions as role_permissions
      FROM user_sessions s
      JOIN users u ON s.user_id = u.id
      JOIN roles r ON u.role_id = r.id
      WHERE s.session_token = ? AND s.expires_at > datetime('now') AND u.is_active = 1
    `);
    
    return stmt.get(sessionToken) as UserWithRole | null;
  }

  // 删除会话（登出）
  deleteSession(sessionToken: string): void {
    const stmt = this.db.prepare('DELETE FROM user_sessions WHERE session_token = ?');
    stmt.run(sessionToken);
  }

  // 获取所有用户
  getAllUsers(): UserWithRole[] {
    const stmt = this.db.prepare(`
      SELECT u.*, r.code as role_code, r.name as role_name, r.permissions as role_permissions
      FROM users u
      JOIN roles r ON u.role_id = r.id
      ORDER BY u.created_at DESC
    `);
    
    return stmt.all() as UserWithRole[];
  }

  // 获取用户详情
  getUserById(id: number): UserWithRole | null {
    const stmt = this.db.prepare(`
      SELECT u.*, r.code as role_code, r.name as role_name, r.permissions as role_permissions
      FROM users u
      JOIN roles r ON u.role_id = r.id
      WHERE u.id = ?
    `);
    
    return stmt.get(id) as UserWithRole | null;
  }

  // 创建用户
  async createUser(userData: {
    username: string;
    password: string;
    email: string;
    full_name: string;
    role_id: number;
    is_active?: boolean;
  }): Promise<number> {
    const hashedPassword = await bcrypt.hash(userData.password, BCRYPT_ROUNDS);
    
    const stmt = this.db.prepare(`
      INSERT INTO users (username, password, email, full_name, role_id, is_active)
      VALUES (?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(
      userData.username,
      hashedPassword,
      userData.email,
      userData.full_name,
      userData.role_id,
      userData.is_active !== false ? 1 : 0
    );
    
    return result.lastInsertRowid as number;
  }

  // 更新用户
  async updateUser(id: number, userData: {
    username?: string;
    password?: string;
    email?: string;
    full_name?: string;
    role_id?: number;
    is_active?: boolean;
  }): Promise<void> {
    const updates: string[] = [];
    const values: any[] = [];
    
    if (userData.username !== undefined) {
      updates.push('username = ?');
      values.push(userData.username);
    }
    
    if (userData.password !== undefined) {
      updates.push('password = ?');
      values.push(await bcrypt.hash(userData.password, BCRYPT_ROUNDS));
    }
    
    if (userData.email !== undefined) {
      updates.push('email = ?');
      values.push(userData.email);
    }
    
    if (userData.full_name !== undefined) {
      updates.push('full_name = ?');
      values.push(userData.full_name);
    }
    
    if (userData.role_id !== undefined) {
      updates.push('role_id = ?');
      values.push(userData.role_id);
    }
    
    if (userData.is_active !== undefined) {
      updates.push('is_active = ?');
      values.push(userData.is_active ? 1 : 0);
    }
    
    if (updates.length === 0) return;
    
    updates.push('updated_at = CURRENT_TIMESTAMP');
    values.push(id);
    
    const stmt = this.db.prepare(`
      UPDATE users SET ${updates.join(', ')} WHERE id = ?
    `);
    
    stmt.run(...values);
  }

  // 删除用户
  deleteUser(id: number): void {
    // 先删除相关会话
    this.db.prepare('DELETE FROM user_sessions WHERE user_id = ?').run(id);
    // 删除用户
    this.db.prepare('DELETE FROM users WHERE id = ?').run(id);
  }

  // 获取所有角色
  getAllRoles(): Role[] {
    const stmt = this.db.prepare('SELECT * FROM roles ORDER BY name');
    return stmt.all() as Role[];
  }

  // 获取角色详情
  getRoleById(id: number): Role | null {
    const stmt = this.db.prepare('SELECT * FROM roles WHERE id = ?');
    return stmt.get(id) as Role | null;
  }

  // 解析角色权限
  parseRolePermissions(permissionsJson: string): RolePermissions {
    try {
      return JSON.parse(permissionsJson) as RolePermissions;
    } catch {
      return {
        canEditAll: false,
        canManageUsers: false,
        canManageRoles: false,
        dataSourceAccess: [],
        editableFields: {}
      };
    }
  }

  // 检查用户是否有权限编辑特定字段
  canUserEditField(user: UserWithRole, tableName: string, fieldName: string, dataSource: string): boolean {
    const permissions = this.parseRolePermissions(user.role_permissions);
    
    // 管理员可以编辑所有字段
    if (permissions.canEditAll) return true;
    
    // 检查数据来源权限
    if (!permissions.dataSourceAccess.includes(dataSource)) return false;
    
    // 检查具体字段权限
    const editableFields = permissions.editableFields?.[tableName] || [];
    return editableFields.includes(fieldName);
  }

  // 获取用户可编辑的字段列表
  getUserEditableFields(user: UserWithRole, tableName: string): string[] {
    const permissions = this.parseRolePermissions(user.role_permissions);
    
    if (permissions.canEditAll) {
      // 管理员返回所有字段（这里需要从字段元数据获取）
      return [];
    }
    
    return permissions.editableFields?.[tableName] || [];
  }

  close(): void {
    this.db.close();
  }
}

// 单例实例
let userManagementInstance: UserManagement | null = null;

export function getUserManagement(): UserManagement {
  if (!userManagementInstance) {
    userManagementInstance = new UserManagement();
  }
  return userManagementInstance;
}
